package erpurlparse

import (
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"net/url"
	"sort"
	"strings"
	"unicode/utf8"

	"github.com/sirupsen/logrus"
)

func ParseAsciiToString(encodedStr string) (str string) { // deprecated
	for i := 0; i < len(encodedStr); {
		char, size := utf8.DecodeRuneInString(encodedStr[i:])
		str += string(char)
		i += size
	}

	return
}

func Parse(queryString, appKey, secret string) (string, bool) {
	var res, sign string
	parameters := map[string]string{}
	subParameters := map[string]any{}
	for _, sections := range strings.Split(queryString, "\u0026") {
		//[app_key T3087752140]
		parts := strings.Split(sections, "=")
		if len(parts) == 2 {
			if parts[0] == "app_key" && parts[1] != appKey {
				res = "" // 强制清空返回值
				break
			}

			switch parts[0] {
			case "app_key":
				parameters["_app"] = parts[1]
			case "data":
				res = strings.ReplaceAll(strings.ReplaceAll(parts[1], "\"[", "["), "]\"", "]")
				res = strings.ReplaceAll(res, "\\\"", "\"")
				// if err := json.Unmarshal([]byte(res), &subParameters); err != nil {
				// 	logx.Errorw("[ERP] Error json.Unmarshal:", logx.Field("detail", err.Error()))
				// 	// [ERP] Error json.Unmarshal:","detail":"json: Unmarshal(non-pointer map[string]interface {})
				// }
				// else {
				// logrus.Info(fmt.Sprintf("[ERP] subParameters: %+v", subParameters))
				// map[item_id:47 quantity:10 shop_nick:shop1820 sku_id:100]
				// }
			case "format":
				// parameters["format"] = parts[1]
			case "timestamp":
				parameters["_t"] = parts[1]
			case "sign":
				sign = parts[1]
			}
		}
	}
	if len(subParameters) > 0 {
		for k, v := range subParameters {
			parameters[k] = fmt.Sprintf("%+v", v)
		}

		// 对参数进行排序
		var keys []string
		for k := range parameters {
			keys = append(keys, k)
		}

		logrus.Info(fmt.Sprintf("[ERP] parameters: %+v", parameters))

		sort.Strings(keys)
		// 拼接参数串
		var content strings.Builder
		for _, k := range keys {
			content.WriteString(k)
			content.WriteString("=")
			content.WriteString(urlEncode(parameters[k]))
			content.WriteString("&")
		}

		// 去掉最后一个 '&' 符号
		contentString := strings.TrimSuffix(content.String(), "&")

		logrus.Info(fmt.Sprintf("[ERP] signContent: %+v", contentString))

		// 生成签名
		signContent := secret + contentString + secret
		md5Hash := md5.Sum([]byte(signContent))
		newSign := hex.EncodeToString(md5Hash[:])
		if sign != newSign {
			logrus.Info(fmt.Sprintf("[ERP] Error sign: %+v , %+v", sign, newSign))
			// 4260640DFB11FB83BA47E957E3EF4C30 , 78c3b1f38090e8e2a8797495d499806d
		}
	}
	if len(res) == 0 {
		return "", false
	}

	return res, true
}

func urlEncode(str string) string {
	encodedStr := url.QueryEscape(str)
	encodedStr = strings.ReplaceAll(encodedStr, "!", "%21")
	encodedStr = strings.ReplaceAll(encodedStr, "'", "%27")
	encodedStr = strings.ReplaceAll(encodedStr, "(", "%28")
	encodedStr = strings.ReplaceAll(encodedStr, ")", "%29")
	encodedStr = strings.ReplaceAll(encodedStr, "~", "%7E")
	encodedStr = strings.ReplaceAll(encodedStr, "%20", "+")

	return encodedStr
}
